package com.sduept.nwld.dataserver.manager.countanalyse;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.sduept.nwld.dataserver.manager.statistics.ProtectKpiManager;
import com.sduept.nwld.dataserver.manager.statistics.StatisticsCommonManager;
import com.sduept.nwld.dataserver.model.countanalyse.FaultFastRemove;
import com.sduept.nwld.dataserver.model.countanalyse.ProtectCorrectAct;


@Service
public class ProtectKpiAnalysisManger {
	@Autowired
	private ProtectKpiManager manager;
	@Autowired
	private StatisticsCommonManager commonM;
	
	private DecimalFormat df=new DecimalFormat("#.##");
	/**
	 * 返回各子公司的保护正确动作数据汇总，一条数据代表一个公司，顺序随机。
	 * @param year 查询该年数据。为null时，返回该公司所有年度数据的和。若该公司某年没有年度数据，查询该年月度数据的总和。
	 * @param month 查询该月数据。为null时，查询年度数据。若该公司没有年度数据，查询月度数据的总和。
	 * @param voltage 220或500。为null时，查询全部电压等级。
	 * @return 返回值中，actNum和unwantedActNum取各数据的和值。reality是前两个数据计算出的值。
	 * plan 取每个plan*actNum的和/actNum的和。
	 * year、month、voltage取参数中的值。
	 */
	public List<ProtectCorrectAct> getSummaryOfCorrectActsBySubCompany(Integer year, Integer month,Integer voltage){
		List<ProtectCorrectAct> rets = new ArrayList<>();
		List<ProtectCorrectAct> list = manager.queryYearData(year, month, voltage);
		HashSet<String> yearSubs = new HashSet<>();
		if(month == null) {
			//遍历出所有的年度数据
			Map<String,ProtectCorrectAct> yearMap = new HashMap<>();//key:公司名
			for(ProtectCorrectAct p:list) {
				if(p.getMonth() == null) {
					addToMap(yearMap,p,voltage,year,month);
					yearSubs.add(p.getSubCompany());
				}
			}
			rets.addAll(yearMap.values());
		}
		//查询月度数据。经过年度数据可以查到的剔除掉。
		Map<String,ProtectCorrectAct> monthMap = new HashMap<>();//key:公司名
		for(ProtectCorrectAct p:list) {
			if(p.getMonth() != null && ! yearSubs.contains(p.getSubCompany())) {
				addToMap(monthMap,p,voltage,year,month);
			}
		}
		rets.addAll(monthMap.values());
		//计算计划百分比和实际百分比
		for(ProtectCorrectAct p:rets) {
			if(p.getActNum() == null || p.getActNum() == 0) {
				p.setReality(100f);
				p.setPlan(getAveragePlanProtectAct(list,p.getSubCompany()));
			}else {
				p.setReality(100f*(1-(float)p.getUnwantedActNum()/p.getActNum()));
				p.setPlan(100f*((float)p.getPlan()/p.getActNum()));
			}
		}
		return rets;
	}
	/**
	 * 和原getSummaryOfCorrectActsBySubCompany方法区分开
	 * @param year
	 * @param month
	 * @param voltage
	 * @return
	 */
	public List<ProtectCorrectAct> getSummaryOfCorrectActsBySubCompany(Integer year, Integer month,Integer voltage, int unitType){
		List<ProtectCorrectAct> list = manager.queryYearData(year, month, voltage, unitType);
		return list;
	}
	
	/**
	 * 根据条件查询
	 * @param year
	 * @param month
	 * @param voltage
	 * @param unitType 单位类型
	 * @param unit 单位名称
	 * @return
	 */
	public List<ProtectCorrectAct> getSummaryOfCorrectActsBySubCompany(Integer year, Integer month,Integer voltage, int unitType, List<String> unit){
		List<ProtectCorrectAct> list = manager.queryYearData(year, month, voltage, unitType, unit);
		return list;
	}
	
	private Float getAveragePlanProtectAct(List<ProtectCorrectAct> list,String subCompany) {
		//年的算一份
		Float yearSum = 0f;
		Integer yearNum = 0;
		//月的算一份
		Float monthSum = 0f;
		Integer monthNum = 0;
		
		for(ProtectCorrectAct p:list) {
			if(null != p.getPlan() && subCompany.equals(p.getSubCompany())) {
				if(p.getMonth() == null) {
					yearSum += p.getPlan();
					yearNum++;
				}else {
					monthSum += p.getPlan();
					monthNum ++;
				}
			}
		}
		Float ave = null;
		if(yearNum != 0) {
			ave = yearSum/yearNum;
		}else if(monthNum != 0){
			ave = monthSum/monthNum;
		}
		return ave;
	}
	private Float getAveragePlanFaultRemove(List<FaultFastRemove> list,String subCompany) {
		//年的算一份
		Float yearSum = 0f;
		Integer yearNum = 0;
		//月的算一份
		Float monthSum = 0f;
		Integer monthNum = 0;
		
		for(FaultFastRemove p:list) {
			if(null != p.getPlan() && subCompany.equals(p.getSubCompany())) {
				if(p.getMonth() == null) {
					yearSum += p.getPlan();
					yearNum++;
				} else {
					monthSum += p.getPlan();
					monthNum ++;
				}
			}
		}
		Float ave = null;
		if(yearNum != 0) {
			ave = yearSum/yearNum;
		}else if(monthNum != 0){
			ave = monthSum/monthNum;
		}
		return ave;
	}
	
	private void addToMap(Map<String,ProtectCorrectAct> map,ProtectCorrectAct p, Integer voltage,Integer year,Integer month) {
		ProtectCorrectAct mp = map.get(p.getSubCompany());
		if(mp == null) {
			mp = new ProtectCorrectAct();
			mp.setActNum(p.getActNum());
			mp.setUnwantedActNum(p.getUnwantedActNum());
			mp.setYear(year);
			mp.setMonth(month);
			mp.setSubCompany(p.getSubCompany());
			mp.setVoltage(voltage);
			if(p.getActNum() != null && p.getPlan() != null) {
				mp.setPlan(p.getActNum()*p.getPlan()/100f);
			}
			map.put(p.getSubCompany(), mp);
		}else {
			if(null != p.getActNum() && null != mp.getActNum()) {
				mp.setActNum(p.getActNum()+mp.getActNum());
			}
			if(null != p.getUnwantedActNum() && null != mp.getUnwantedActNum()) {
				mp.setUnwantedActNum(p.getUnwantedActNum()+mp.getUnwantedActNum());
			}
			if(null != p.getActNum() && null != p.getPlan() && null!=mp.getPlan()) {
				mp.setPlan(mp.getPlan()+p.getActNum()*p.getPlan()/100f);
			}
		}
	}
	/**
	 * 返回各子公司的保护正确动作数据汇总，一条数据代表一个公司，顺序随机。
	 * @param year 查询该年数据。为null时，返回该公司所有年度数据的和。若该公司某年没有年度数据，查询该年月度数据的总和。
	 * @param month 查询该月数据。为null时，查询年度数据。若该公司没有年度数据，查询月度数据的总和。
	 * @param voltage 220或500。为null时，查询全部电压等级。
	 * @return 返回值中，actNum和unwantedActNum取各数据的和值。reality是前两个数据计算出的值。
	 * plan 取每个plan*actNum的和/actNum的和。
	 * year、month、voltage取参数中的值。
	 */
	public List<FaultFastRemove> getSummaryOfFaultFastRemoveBySubCompany(Integer year, Integer month,Integer voltage){
		List<FaultFastRemove> rets = new ArrayList<>();
		List<FaultFastRemove> list = manager.queryRemoveYearData(year, month, voltage);
		HashSet<String> yearSubs = new HashSet<>();
		if(month == null) {
			//遍历出所有的年度数据
			Map<String,FaultFastRemove> yearMap = new HashMap<>();//key:公司名
			for(FaultFastRemove p:list) {
				if(p.getMonth() == null) {
					addToMap(yearMap,p,voltage,year,month);
					yearSubs.add(p.getSubCompany());
				}
			}
			rets.addAll(yearMap.values());
		}
		//查询月度数据。经过年度数据可以查到的剔除掉。
		Map<String,FaultFastRemove> monthMap = new HashMap<>();//key:公司名
		for(FaultFastRemove p:list) {
			if(p.getMonth() != null && ! yearSubs.contains(p.getSubCompany())) {
				addToMap(monthMap,p,voltage,year,month);
			}
		}
		rets.addAll(monthMap.values());
		//计算计划百分比和实际百分比
		for(FaultFastRemove p:rets) {
			if(p.getActNum() == null || p.getActNum() == 0) {
				p.setReality(100f);
				p.setPlan(getAveragePlanFaultRemove(list,p.getSubCompany()));
			}else {
				p.setReality(100f*((float)p.getWantedActNum()/p.getActNum()));
				p.setPlan(100f*((float)p.getPlan()/p.getActNum()));
			}
		}
		return rets;
	}
	/**
	 * 和原getSummaryOfFaultFastRemoveBySubCompany方法区分开
	 * @param year
	 * @param month
	 * @param voltage
	 * @return
	 */
	public List<FaultFastRemove> getSummaryOfFaultFastRemoveBySubCompany(Integer year, Integer month, Integer voltage, int unitType){
		List<FaultFastRemove> list = manager.queryRemoveYearData(year, month, voltage, unitType);
		return list;
	}
	
	/**
	 * 根据条件查询
	 * @param year
	 * @param month
	 * @param voltage
	 * @param unitType 单位类型
	 * @param unit 单位名称
	 * @return
	 */
	public List<FaultFastRemove> getSummaryOfFaultFastRemoveBySubCompany(Integer year, Integer month, Integer voltage, int unitType,  List<String> unit){
		List<FaultFastRemove> list = manager.queryRemoveYearData(year, month, voltage, unitType, unit);
		return list;
	}
	
	private void addToMap(Map<String,FaultFastRemove> map,FaultFastRemove p, Integer voltage,Integer year,Integer month) {
		FaultFastRemove mp = map.get(p.getSubCompany());
		if(mp == null) {
			mp = new FaultFastRemove();
			mp.setActNum(p.getActNum());
			mp.setWantedActNum(p.getWantedActNum());
			mp.setYear(year);
			mp.setMonth(month);
			mp.setVoltage(voltage);
			mp.setSubCompany(p.getSubCompany());
			if(p.getActNum() != null && p.getPlan() != null) {
				mp.setPlan(p.getActNum()*p.getPlan()/100f);
			}
			map.put(p.getSubCompany(), mp);
		}else {
			if(null != p.getActNum() && null != mp.getActNum()) {
				mp.setActNum(p.getActNum()+mp.getActNum());
			}
			if(null != p.getWantedActNum() && null != mp.getWantedActNum()) {
				mp.setWantedActNum(p.getWantedActNum()+mp.getWantedActNum());
			}
			if(null != p.getActNum() && null != p.getPlan() && null != mp.getPlan()) {
				mp.setPlan(mp.getPlan()+p.getActNum()*p.getPlan()/100f);
			}
		}
	}

	/**
	 * 将List<FaultFastRemove>转为json
	 * @param ffrs
	 * @return
	 */
	public String getFaultFastRemove(List<FaultFastRemove> ffrs) {
		JSONObject json = new JSONObject();
		//全网的情况
		float allPlanNum = 0f;
		float allActNum = 0f;
		float allWantedActNum = 0f;
		
		//作为ActNum为0时的备用
		float planSum = 0f;
		float planNum = 0f;
		
		//各子公司的情况
		if(ffrs.size()>0) {
			StringBuffer buff = new StringBuffer();
			buff.append("[");
			List<String> subCompanys = commonM.getSubCompanys();
			// 保证图中所展示的公司顺序是固定的
			for (String com : subCompanys) {
				// 公司名称
				buff.append("{name:'" + com + "',");
				boolean flag = false;
				for (FaultFastRemove ffr : ffrs) {
					if(ffr.getSubCompany().equals(com)) {
						flag = true;
						// 计划完成率
						String ffrPlan = ffr.getPlan() == null?"NaN":df.format(ffr.getPlan());
						buff.append("plan:'"+ffrPlan+"',");
						// 实际完成率
						String ffrReality = ffr.getReality() == null?"NaN":df.format(ffr.getReality());
						buff.append("reality:'"+ffrReality+"'},");
						if(ffr.getActNum() != null) {
							allActNum += ffr.getActNum();
							if(ffr.getPlan() != null) {
								allPlanNum += ffr.getPlan()*ffr.getActNum()/100;
								planSum += ffr.getPlan();
								planNum ++;
							}
						}
						if(ffr.getWantedActNum() != null)
							allWantedActNum += ffr.getWantedActNum();
					}
				}
				if(!flag) {
					buff.append("plan:'NaN',reality:'NaN'},");
				}
			}
			buff.append("]");
			json.put("groups", JSONObject.parse(buff.toString()));
			
			//该电压等级下，全网的情况
			Float allPlan = null;
			Float allReality = null;
			if(allActNum != 0) {
				allPlan = 100f*allPlanNum/allActNum;
				allReality = 100f*(allWantedActNum/allActNum);
			}else {
				if(planNum>0) {
					allPlan = planSum/planNum;
				}
			}
			String ap = "\'NaN\'";
			if(null != allPlan) {
				ap = df.format(allPlan);
			}
			String ar = "\'NaN\'";
			if(null != allReality) {
				ar = df.format(allReality);
			}
			json.put("all", JSONObject.parse("{plan:"+ap+",reality:"+ar+"}"));
		} else {
			json = initEmptyChartData();
		}
		return json.toJSONString();
	}
	/**
	 * 将List<FaultFastRemove>转为json，和原getFaultFastRemove方法区分开
	 * @param ffrs
	 * @return
	 */
	public String getFaultFastRemoveTwo(List<FaultFastRemove> ffrs, int unitType, List<String> unitFilter) {
		JSONObject json = new JSONObject();
		//全网的情况
		float allPlanNum = 0f;
		float allActNum = 0f;
		float allWantedActNum = 0f;
		
		//作为ActNum为0时的备用
		float planSum = 0f;
		float planNum = 0f;
		
		//各子公司的情况
		if(ffrs.size()>0) {
			List<String> units = new ArrayList<String>();
			if(unitType == 0) {//类型是检修单位，有单位筛选
				units.addAll(unitFilter);
			}else {
				units = commonM.getAllUnits(unitType);//根据类型获取单位信息
			}
			//找出没有统计数据的单位
			for (FaultFastRemove ffr : ffrs) {
				String subCompany = ffr.getSubCompany();//单位
				if(units.contains(subCompany)) {
					units.remove(subCompany);
				}
			}
			//没有统计数据的单位默认设置为100%，保持展示形状
			for(String unit : units) {
				FaultFastRemove ffr = new FaultFastRemove();
				ffr.setSubCompany(unit);
				ffr.setPlan(100f);
				ffr.setReality(100f);
				ffrs.add(ffr);
			}
			StringBuffer buff = new StringBuffer();
			buff.append("[");
			for (FaultFastRemove ffr : ffrs) {
				buff.append("{name:'" + ffr.getSubCompany() + "',");
				// 计划完成率
				String ffrPlan = ffr.getPlan() == null?"NaN":df.format(ffr.getPlan());
				buff.append("plan:'"+ffrPlan+"',");
				// 实际完成率
				String ffrReality = ffr.getReality() == null?"NaN":df.format(ffr.getReality());
				buff.append("reality:'"+ffrReality+"'},");
				if(ffr.getActNum() != null) {
					allActNum += ffr.getActNum();
					if(ffr.getPlan() != null) {
						allPlanNum += ffr.getPlan()*ffr.getActNum()/100;
						planSum += ffr.getPlan();
						planNum ++;
					}
				}
				if(ffr.getWantedActNum() != null)
					allWantedActNum += ffr.getWantedActNum();
			}
			buff.append("]");
			json.put("groups", JSONObject.parse(buff.toString()));
			
			//该电压等级下，全网的情况
			Float allPlan = null;
			Float allReality = null;
			if(allActNum != 0) {
				allPlan = 100f*allPlanNum/allActNum;
				allReality = 100f*(allWantedActNum/allActNum);
			}else {
				if(planNum>0) {
					allPlan = planSum/planNum;
				}
			}
			String ap = "\'NaN\'";
			if(null != allPlan) {
				ap = df.format(allPlan);
			}
			String ar = "\'NaN\'";
			if(null != allReality) {
				ar = df.format(allReality);
			}
			json.put("all", JSONObject.parse("{plan:"+ap+",reality:"+ar+"}"));
		} else {
			json = initEmptyChartData(unitType, unitFilter);
		}
		return json.toJSONString();
	}
	
	/**
	 * 将List<ProtectCorrectAct>转为json
	 * @param acts
	 * @return
	 */
	public String getProtectCorrectAct(List<ProtectCorrectAct> acts) {
		JSONObject json = new JSONObject();
		//全网的情况
		float allPlanNum = 0f;
		float allActNum = 0f;
		float allUnwantedActNum = 0f;
		
		//作为ActNum为0时的备用
		float planSum = 0f;
		float planNum = 0f;
		
		//各子公司的情况
		if(acts.size()>0) {
			StringBuffer buff = new StringBuffer();
			buff.append("[");
			List<String> subCompanys = commonM.getSubCompanys();
			for (String com : subCompanys) {
				//公司名称
				buff.append("{name:'" + com + "',");
				boolean flag = false;
				for (ProtectCorrectAct act : acts) {
					if(act.getSubCompany().equals(com)) {
						flag = true;
						// 计划完成率
						buff.append("{name:'" + act.getSubCompany() + "',");
						String actPlan = (act.getPlan() == null?"NaN":df.format(act.getPlan()));
						buff.append("plan:'"+actPlan+"',");
						// 实际完成率
						String actReality = (act.getReality() == null?"NaN":df.format(act.getReality()));
						buff.append("reality:'"+actReality+"'},");
						
						if(act.getActNum() != null) {
							allActNum += act.getActNum();
							if(act.getPlan() != null) {
								allPlanNum += act.getPlan()*act.getActNum()/100;
								planSum += act.getPlan();
								planNum ++;
							}
						}
						if(act.getUnwantedActNum() != null)
							allUnwantedActNum += act.getUnwantedActNum();
					}
				}
				if(!flag) {
					buff.append("plan:'NaN',reality:'NaN'},");
				}
			}
			
			buff.append("]");
			json.put("groups", JSONObject.parse(buff.toString()));
			
			//该电压等级下，全网的情况
			Float allPlan = null;
			Float allReality = null;
			if(allActNum != 0) {
				allPlan = 100f*allPlanNum/allActNum;
				allReality = 100f*(1-allUnwantedActNum/allActNum);
			}else {
				if(planNum>0) {
					allPlan = planSum/planNum;
				}
			}
			String ap = "\'NaN\'";
			if(null != allPlan) {
				ap = df.format(allPlan);
			}
			String ar = "\'NaN\'";
			if(null != allReality) {
				ar = df.format(allReality);
			}
			json.put("all", JSONObject.parse("{plan:"+ap+",reality:"+ar+"}"));
		} else {
			json = initEmptyChartData();
		}
		return json.toJSONString();
	}
	
	/**
	 * 将List<ProtectCorrectAct>转为json，和getProtectCorrectAct方法区分开
	 * @param acts
	 * @return
	 */
	public String getProtectCorrectActTwo(List<ProtectCorrectAct> acts, int unitType, List<String> unitFilter) {
		JSONObject json = new JSONObject();
		//全网的情况
		float allPlanNum = 0f;
		float allActNum = 0f;
		float allUnwantedActNum = 0f;
		
		//作为ActNum为0时的备用
		float planSum = 0f;
		float planNum = 0f;
		//各子公司的情况
		if(acts.size()>0) {
			List<String> units = new ArrayList<String>();
			if(unitType == 0) {//类型是检修单位，有单位筛选
				units.addAll(unitFilter);
			}else {
				units = commonM.getAllUnits(unitType);//根据类型获取单位信息
			}
			//找出没有统计数据的单位
			for (ProtectCorrectAct act : acts) {
				String subCompany = act.getSubCompany();//单位
				if(units.contains(subCompany)) {
					units.remove(subCompany);
				}
			}
			//没有统计数据的单位默认设置为100%，保持展示形状
			for(String unit : units) {
				ProtectCorrectAct pca = new ProtectCorrectAct();
				pca.setSubCompany(unit);
				pca.setPlan(100f);
				pca.setReality(100f);
				acts.add(pca);
			}
			StringBuffer buff = new StringBuffer();
			buff.append("[");
			for (ProtectCorrectAct act : acts) {
				// 计划完成率
				buff.append("{name:'" + act.getSubCompany() + "',");
				String actPlan = (act.getPlan() == null?"NaN":df.format(act.getPlan()));
				buff.append("plan:'"+actPlan+"',");
				// 实际完成率
				String actReality = (act.getReality() == null?"NaN":df.format(act.getReality()));
				buff.append("reality:'"+actReality+"'},");
				
				if(act.getActNum() != null) {
					allActNum += act.getActNum();
					if(act.getPlan() != null) {
						allPlanNum += act.getPlan()*act.getActNum()/100;
						planSum += act.getPlan();
						planNum ++;
					}
				}
				if(act.getUnwantedActNum() != null)
					allUnwantedActNum += act.getUnwantedActNum();
			}
			
			buff.append("]");
			json.put("groups", JSONObject.parse(buff.toString()));
			
			//该电压等级下，全网的情况
			Float allPlan = null;
			Float allReality = null;
			if(allActNum != 0) {
				allPlan = 100f*allPlanNum/allActNum;
				allReality = 100f*(1-allUnwantedActNum/allActNum);
			}else {
				if(planNum>0) {
					allPlan = planSum/planNum;
				}
			}
			String ap = "\'NaN\'";
			if(null != allPlan) {
				ap = df.format(allPlan);
			}
			String ar = "\'NaN\'";
			if(null != allReality) {
				ar = df.format(allReality);
			}
			json.put("all", JSONObject.parse("{plan:"+ap+",reality:"+ar+"}"));
		} else {
			json = initEmptyChartData(unitType, unitFilter);
		}
		return json.toJSONString();
	}
	
	// 当没有数据时，页面显示一个空图
	private JSONObject initEmptyChartData() {
		JSONObject json = new JSONObject();
		StringBuffer buff = new StringBuffer();
		buff.append("[");
		List<String> subCompanys = commonM.getSubCompanys();
		for (String com : subCompanys) {
			buff.append("{name:'" + com + "',plan:'NaN',reality:'NaN'},");
		}
		buff.append("]");
		json.put("groups", JSONObject.parse(buff.toString()));
		json.put("all", JSONObject.parse("{plan:'NaN',reality:'NaN'}"));
		return json;
	}
	
	/**
	 * 当没有数据时，页面显示一个空图
	 * @param unitType 单位类型（0：检修单位，1：调管单位）
	 * @return
	 */
	private JSONObject initEmptyChartData(int unitType, List<String> unitFilter) {
		JSONObject json = new JSONObject();
		StringBuffer buff = new StringBuffer();
		buff.append("[");
//		if(unitType == 0) {
//			String sql = "select primaryEquipmentScope from t_substation_ledger where primaryEquipmentScope is not null "
//				+ "and primaryEquipmentScope != '' group by primaryEquipmentScope";
//			List<String> maintenanceUnit = (List<String>) dao.nativeQuery(sql);
//			for (String unit : maintenanceUnit) {
//				buff.append("{name:'" + unit + "',plan:'NaN',reality:'NaN'},");
//			}
//		}else {
//			String sql = "select dispatchUnit from t_substation_ledger where dispatchUnit is not null and dispatchUnit "
//				+ "!= '' group by dispatchUnit";
//			List<String> dispatchUnit = (List<String>) dao.nativeQuery(sql);
//			for (String unit : dispatchUnit) {
//				buff.append("{name:'" + unit + "',plan:'NaN',reality:'NaN'},");
//			}
//		}
		List<String> subCompanys = new ArrayList<String>();
		if(unitType == 0) {//类型是检修单位，有单位筛选
			subCompanys.addAll(unitFilter);
		}else {
			subCompanys = commonM.getAllUnits(unitType);
		}
		for (String com : subCompanys) {
			buff.append("{name:'" + com + "',plan:'NaN',reality:'NaN'},");
		}
		buff.append("]");
		json.put("groups", JSONObject.parse(buff.toString()));
		json.put("all", JSONObject.parse("{plan:'NaN',reality:'NaN'}"));
		return json;
	}
}
